package exportdemo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.springframework.util.StringUtils;

/**
 * <p>Title:  ExportUtils </p>
 * <p>Description: 功能描述：数据导出工具类 </p>
 * @author  Nelson
 * @date  2020/6/30 11:29
 * @version 1.0
 */
public class ExportUtils {
  public static final String DEFAULT_SEPERATOR = ",";
  public static final String SPECIAL_SEPERATOR = "||$#T&4%%sa~@||";
  public static final String CSV_SUFFIX = ".csv";
  public static final String CHARSET_UTF8 = "UTF-8";
  
  /**
   * 功能说明：获取UTF-8编码文本文件开头的BOM签名。 BOM(Byte Order Mark)，是UTF编码方案里用于标识编码的标准标记。
   * 例：接收者收到以EF BB BF开头的字节流，就知道是UTF-8编码。
   * 
   * @return UTF-8编码文本文件开头的BOM签名
   */
  public static String getBOM() {
    byte b[] = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
    return new String(b);
  }
  
  /**
   * 功能描述：导出文件(逗号分隔符)
   *
   * @param filePath
   * @param headers
   * @param exportData
   */
  public static void exportFile(String filePath, String[] headers, List<String[]> exportData) {
    exportFile(filePath, headers, exportData, DEFAULT_SEPERATOR, CHARSET_UTF8);
  }
  /**
   * 功能描述：导出文件(自定义分隔符)
   *
   * @param filePath
   * @param headers
   * @param exportData
   * @param seperator
   */
  public static void exportFile(String filePath, String[] headers, List<String[]> exportData, String seperator) {
    exportFile(filePath, headers, exportData, seperator, CHARSET_UTF8);
  }

  /**
   * 功能描述：导出文件(自定义参数)
   *
   * @param filePath
   * @param headers
   * @param exportData
   * @param seperator
   * @param charSet
   */
  public static void exportFile(String filePath, String[] headers, List<String[]> exportData, String seperator, String charSet) {
    File csvFile = null;
    BufferedWriter csvFileOutputStream = null;
    try {
      // 定义文件名格式并创建
      csvFile = new File(filePath);
      if (!csvFile.getParentFile().exists()) {
        csvFile.getParentFile().mkdirs();
      }
      // UTF-8使正确读取分隔符","
      // 如果生产文件乱码，Windows下用GBK，Linux用UTF-8
      csvFileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvFile), charSet), 1024);

      // 写入前段字节流，防止乱码
      csvFileOutputStream.write(getBOM());
      
      // 写入文件头部
      List<String> headersInList = Arrays.asList(headers);
      for (Iterator<String> headersIterator = headersInList.iterator(); headersIterator.hasNext();) {
        String header = headersIterator.next();
        csvFileOutputStream.write(header != null ? header : "");
        if (headersIterator.hasNext()) {
          csvFileOutputStream.write(",");
        }
      }
      csvFileOutputStream.newLine();

      // 写入文件内容
      for (Iterator<String[]> exportDataIterator = exportData.iterator(); exportDataIterator.hasNext();) {
        String[] row = exportDataIterator.next();
        List<String> rowInList = Arrays.asList(row);
        for (Iterator<String> propertyIterator = rowInList.iterator(); propertyIterator.hasNext();) {
          String rowData = propertyIterator.next();
          String str = (rowData != null ? rowData : "");
          if (StringUtils.isEmpty(str)) {
            str = "";
          } else {
            str = str.replaceAll("\"", "\"\"");
            if (str.indexOf(",") >= 0) {
              str = "\"" + str + "\"";
            }
          }
          csvFileOutputStream.write(str);
          if (propertyIterator.hasNext()) {
            csvFileOutputStream.write(seperator);
          }
        }
        if (exportDataIterator.hasNext()) {
          csvFileOutputStream.newLine();
        }
      }
      csvFileOutputStream.flush();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        csvFileOutputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 功能描述：测试
   *
   * @param args
   */
  public static void main(String[] args) {
    // 表头
    String[] headers = new String[] { "第一列名称", "第二列名称", "第三列名称", "第四列名称" };
    // 数据
    String[] row1 = new String[] {"1", "2", "3", "4"};
    String[] row2 = new String[] {"11", "22", "33", "44"};
    List<String[]> exportData = Arrays.asList(row1, row2);
    // 分隔符
    String seperator = "||$#T&4%%sa~@||";

    // 文件导出路径
    String path = "D:/";
    // 文件名
    String fileName = "特殊分隔符文件导出.csv";
    String filePath = path + fileName;

    ExportUtils.exportFile(filePath, headers, exportData);
  }
}
